﻿/*
 * Decoder
 * 
 * initial implementation : 3.12.2008
 *
 * Copyright (c) Adam Sida, asida@centrum.cz.
 * All rights reserved.
 * 
 * for license see Petra.Gis.License.txt
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Petra.Gis.ImagingServices;
using Petra.Gis.ImagingServices.Cit;


namespace Petra.Gis.ImagingServices
{


  /// <summary>
  /// decoder for Intergrapg Cit image data format.
  /// Cit is Image File Format (.cit file extension) with Class B-CCITT group 4 fax compression
  /// </summary>
  public class CitBitmapDecoder : GridBitmapDecoderBase
  {

    private CitCodecInfo _cInfo;

    //public CitBitmapDecoder(Stream citStream, bool decodeAs8bpp, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption)
    public CitBitmapDecoder(Stream citStream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption)
      : base(citStream, createOptions, cacheOption)
    {
      _cInfo = new CitCodecInfo();

      //if (_createOptions == BitmapCreateOptions.PreservePixelFormat)
      //  _loadAsPaletted8bpp = false;
      //else
      //  _loadAsPaletted8bpp = true;

      BinaryReader citReader = new BinaryReader(_data);

      //try read magic numbers...
      readHeaderMagicNumber(citReader);

      //cit is single frame image...
      prepareFrames(_data);
    
    }




    public CitBitmapDecoder(Uri FileUri, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption)
      : base(FileUri, createOptions, cacheOption)
    {
      _cInfo = new CitCodecInfo();

      BinaryReader citReader = new BinaryReader(_data);

      //try read magic numbers...
      readHeaderMagicNumber(citReader);

      //cit is single frame image...
      prepareFrames(_data);
    }




    //private bool _loadAsPaletted8bpp = true;

    ///// <summary>
    ///// cit is CCITT G4 2d compression for bilevel images only
    ///// if LoadAsPaletted8bpp is set to true then image is loaded into 8bpp bitmap with colortable
    ///// background is transparent black, foreground is white.
    ///// usefull for data display
    ///// </summary>
    //public bool LoadAsPaletted8bpp
    //{
    //  get { return _loadAsPaletted8bpp; }
    //  set 
    //  {
    //    _loadAsPaletted8bpp = value;
    //    prepareFrames(_citStream);
    //  }
    //}






    private System.Collections.ObjectModel.ReadOnlyCollection<BitmapFrame> _frames;

    public override System.Collections.ObjectModel.ReadOnlyCollection<BitmapFrame> Frames
    {
      get { return _frames; }
    }





    public override BitmapCodecInfo CodecInfo
    {
      get { return _cInfo; }
    }


    #region private members


    protected ushort readHeaderMagicNumber(BinaryReader citReader)
    {

      ushort magic;

      //ushort h = _citReader.ReadUInt16();
      //byte igds_element_type = _citReader.ReadByte();
      magic = citReader.ReadUInt16();
      //result.IgdsMagic = _citReader.ReadUInt16();

      //if(igds_element_type != 9)
      if (magic != 0x0908)
        throw new ArgumentException("not a ingr file");


      ////byte igds_major = _citReader.ReadByte();
      //result.DimensionAndVersion = _citReader.ReadByte();

      //// only version 8 is supported
      //if ((result.DimensionAndVersion & 63) != 8)
      //  throw new ArgumentException("unsupported version " + (result.DimensionAndVersion & 63).ToString());

      //// must be 2d or 3d
      //if ((result.DimensionAndVersion & 192) != 0 && (result.DimensionAndVersion & 192) != 192)
      //  throw new ArgumentException("not a ingr file");

      //// cit must be 2d
      //if ((result.DimensionAndVersion & 192) != 0)
      //  throw new ArgumentException("not a cit file");

      return magic;

    }





    protected void prepareFrames(Stream citStream)
    {

      CitBitmap cb = CitBitmap.Create(citStream, _createOptions, _cacheOption);

      List<BitmapFrame> bfs = new List<BitmapFrame>();
      bfs.Add(BitmapFrame.Create(cb));

      _frames = new System.Collections.ObjectModel.ReadOnlyCollection<BitmapFrame>(bfs);

      //FileStream stream = new FileStream(@"c:\temp\new.tif", FileMode.Create);
      //TiffBitmapEncoder encoder = new TiffBitmapEncoder();
      //encoder.Compression = TiffCompressOption.Ccitt4;
      //encoder.Frames.Add(BitmapFrame.Create(data));
      //encoder.Save(stream);

    }





    //protected MinMaxType readMinMaxType()
    //{
    //  MinMaxType result = new MinMaxType()
    //  {
    //    AsUint8 = _citReader.ReadByte(),
    //    AsUint16 = _citReader.ReadUInt16(),
    //    AsUint32 = _citReader.ReadUInt32(),
    //    AsReal32 = _citReader.ReadSingle(),
    //    AsReal64 = _citReader.ReadDouble()
    //  };

    //  return result;

    //}





    //protected TileDirectory readCitTileDirecotry()
    //{
    //  TileDirectory result = new TileDirectory()
    //  {
    //    ApplicationType = _citReader.ReadUInt16(),
    //    SubTypeCode = _citReader.ReadUInt16(),
    //    WordsToFollow = _citReader.ReadUInt32(),
    //    PacketVersion = _citReader.ReadUInt16(),
    //    Identifier = _citReader.ReadUInt16(),
    //    Reserved = new ushort[2] { _citReader.ReadUInt16(), _citReader.ReadUInt16() },//2
    //    Properties = _citReader.ReadUInt16(),
    //    DataTypeCode = (DataCodeType)_citReader.ReadUInt16(),
    //    Reserved2 = _citReader.ReadBytes(100), //100
    //    TileSize = _citReader.ReadUInt32(),
    //    Reserved3 = _citReader.ReadUInt32(),
    //  };

    //  // validation..
    //  if (result.ApplicationType != 1 ||
    //      result.SubTypeCode != 7 ||
    //      (result.WordsToFollow % 4 != 0) ||
    //      result.PacketVersion != 1 ||
    //      result.Identifier != 1 ||
    //      result.Reserved3 != 0)
    //    throw new ArgumentException("not a valid tile directory");

    //  // load tiles
    //  for (int i = 0; i < result.WordsToFollow; i++)
    //    result.Tiles.Add(readTile());


    //  return result;
    //}



   // protected TileItem readTile()
   //{
   //  TileItem result = new TileItem()
   //  {
   //     Allocated = _citReader.ReadUInt32(),
   //     Start = _citReader.ReadUInt32(),
   //     Used = _citReader.ReadUInt32()
   //  };

   //  return result;
    //}



    #endregion private members





  }



  


  
}
